package main;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.text.MessageFormat;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.text.DefaultCaret;

public class TextPad extends JFrame implements ActionListener{
	
	java.net.URL openimageURL = TextPad.class.getResource("opensmall.png");
	java.net.URL newimageURL = TextPad.class.getResource("newsmall.png");
	java.net.URL saveimageURL = TextPad.class.getResource("savesmall.png");
	java.net.URL printimageURL = TextPad.class.getResource("printsmall.png");
	java.net.URL iconimageURL = TextPad.class.getResource("Venus.gif");
	private JButton openButton = new JButton(new ImageIcon(openimageURL));
	/**newButton for save event.*/
	private JButton newButton = new JButton(new ImageIcon(newimageURL));
	
	/**saveButton for save event.*/
	private JButton saveButton = new JButton(new ImageIcon(saveimageURL));
	/**printButton for print event.*/
	private JButton printButton = new JButton(new ImageIcon(printimageURL));
	
	
    

	
    /**toolsMenu for Menu on the menu bar.*/
	private JMenu toolsMenu = new JMenu("Menu");
	
	private JMenuItem open = new JMenuItem("Open");
	private JMenuItem newItem = new JMenuItem("New");
	private JMenuItem save = new JMenuItem("Save");
	private JMenuItem print = new JMenuItem("Print");
	private JMenuItem exitItem = new JMenuItem("Exit");
	
	
	
	private JTextPane logArea = new JTextPane();
	
	private JScrollPane logAreaScrollPane = new JScrollPane(this.logArea);
	
    /**bgcolor for background color when mouse over button.*/
    private Color bgcolor = new Color(225,240,255);
    
    /**switch variable for the JFileChooser save dialog.*/
	private boolean done = false;
	
	private int savecount = 0;
	private boolean saved = false;
	
	private File currentfile = null;
	
	public TextPad()
	{
		super("TextPad");
		this.setIconImage(Toolkit.getDefaultToolkit().getImage(iconimageURL));
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// Creates a menubar for a JFrame
        JMenuBar menuBar = new JMenuBar();
        menuBar.setBackground(bgcolor);
        // Add the menubar to the frame
        this.setJMenuBar(menuBar);
        
        
        //add buttons to ActionListener and menubar
        openButton.addActionListener(this);
        newButton.addActionListener(this);
        saveButton.addActionListener(this);
        printButton.addActionListener(this);
        
        open.addActionListener(this);
        newItem.addActionListener(this);
        save.addActionListener(this);
        print.addActionListener(this);

        exitItem.addActionListener(this);
        
        open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
        newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
        save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));    
        print.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.CTRL_MASK));
  
        exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK));
        
        open.setIcon(new ImageIcon(openimageURL));
        print.setIcon(new ImageIcon(printimageURL));
        save.setIcon(new ImageIcon(saveimageURL));
        newItem.setIcon(new ImageIcon(newimageURL));
        
        toolsMenu.add(open);
        toolsMenu.add(newItem);
        toolsMenu.add(save);
        toolsMenu.add(print);
        
        
        
        toolsMenu.addSeparator();
        
        toolsMenu.add(exitItem);
        
        
        menuBar.add(openButton);
        menuBar.add(newButton);
        menuBar.add(saveButton);
        menuBar.add(printButton);
        menuBar.add(toolsMenu);
        
        
        
        
        this.openButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        this.openButton.setToolTipText("Open a text file.");
        //change the button color when mouse over the button
		openButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                openButton.setBackground(Color.white);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                openButton.setBackground(UIManager.getColor("control"));
            }
        });
		
        this.newButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        this.newButton.setToolTipText("Open a new window.");
        //change the button color when mouse over the button
		newButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                newButton.setBackground(Color.white);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                newButton.setBackground(UIManager.getColor("control"));
            }
        });
		
        this.saveButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        this.saveButton.setToolTipText("Save the file.");
        //change the button color when mouse over the button
		saveButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                saveButton.setBackground(Color.white);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                saveButton.setBackground(UIManager.getColor("control"));
            }
        });
		
        this.printButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        this.printButton.setToolTipText("Print the file.");
        //change the button color when mouse over the button
		printButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                printButton.setBackground(Color.white);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                printButton.setBackground(UIManager.getColor("control"));
            }
        });
		

        JPanel txtPanel = new JPanel();
        txtPanel.setLayout(new BoxLayout(txtPanel, BoxLayout.PAGE_AXIS));
        txtPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
        
        
        logArea.setEditable(true);
		// Use monospaced font so tables look nice
		Font font = Font.decode(Font.MONOSPACED);
		logArea.setFont(font);
		//logAreaScrollPane.setSize(400,400);
		// Set the caret to update position automatically as text is appended
		DefaultCaret caret = (DefaultCaret) this.logArea.getCaret();
		caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
		// Always display scroll bars
		logAreaScrollPane
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		logAreaScrollPane
				.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		
		txtPanel.add(logAreaScrollPane, BorderLayout.CENTER);
        
        this.add(txtPanel);
        
        this.setSize(new Dimension(500,600));
        
		// Enable the ENTER key to act as trigger for focused button
		UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);
        this.setVisible(true);
	}
	
	public static void main (String [] args)
	{
		TextPad tp = new TextPad();
		
	}

	
	public void openFile() throws IOException
	{
		JFileChooser inputFC = new JFileChooser();
		inputFC.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
		ProjectFileFilter pff = new ProjectFileFilter();
		inputFC.setFileFilter(pff);
		inputFC.setMultiSelectionEnabled(false);
		int rc = inputFC.showDialog(this, "Select");
		if (rc == JFileChooser.APPROVE_OPTION) {
			File source = inputFC.getSelectedFile();
			this.currentfile = source;
			//this.sourceTextField.setText(f.getAbsolutePath());
			
			//File source = new File(f.getAbsolutePath());
			byte[] bytes = new byte[(int) source.length()];
			FileInputStream in = null;
			
			try {
				in = new FileInputStream(source);
				if (in.read(bytes) < source.length()) {
					throw new RuntimeException("Error reading " + source.getName());
				}
				in.close();
				in = null;
				String fileContent = new String(bytes);
				this.logArea.setText(fileContent);
				bytes = null;
				return ;
			} finally {
				if (in != null) {
					try {
					in.close();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	@Override
	public void actionPerformed(ActionEvent event) {
		
		if (event.getSource() == this.openButton || event.getSource() == this.open)
		{
			try {
				openFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			this.saved=true;
		}
		else if(event.getSource() == this.printButton || event.getSource() == this.print)
		{
			
			MessageFormat header = new MessageFormat("Page {0,number,integer}");
			
	        try {
	        	//System.out.println("Tab selected is at index: "+this.tabPanel.getSelectedIndex());
	            this.logArea.print();
	        } catch (java.awt.print.PrinterException e) {
	            System.err.format("Can't print %s.%n", e.getMessage());
	        }
			
		}
		else if(event.getSource() == this.saveButton || event.getSource() == this.save)
		{
			
			if(this.currentfile != null || this.saved)
			{
				//System.out.println("hello");
				saving(this.currentfile);
				this.savecount++;
			}
			else
			{
				final MyFileChooser fc = new MyFileChooser();
				ProjectFileFilter pff = new ProjectFileFilter();
				fc.setFileFilter(pff);
				done = false;
				
				 fc.setDialogType(JFileChooser.SAVE_DIALOG);
				 final JDialog dialog = fc.createDialog(null);
				 

				
				fc.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent evt){
					String command = evt.getActionCommand();
					//Set done to true when cancel is pressed
					if(command.equals(JFileChooser.CANCEL_SELECTION)){
					//System.out.println("Cancel was pressed");
					dialog.setVisible(false);
					done = true;
					}
					else if(command.equals(JFileChooser.APPROVE_SELECTION)){
						//System.out.println("Save was pressed");
						File file = fc.getSelectedFile();
						String outputDirectory=fc.getSelectedFile().getParent();
						String filename = file.getName();
						if(!filename.endsWith(".txt"))
							filename= filename + ".txt";
						int res=0;
						if(isFileExists(outputDirectory,filename)){
							res = JOptionPane.showConfirmDialog(null,
	                			"This file already exist, would you like to replace it?",
	                			"Save Confirmation",
	                			JOptionPane.YES_NO_OPTION,
	                			JOptionPane.QUESTION_MESSAGE);
							}
	    
						if(res==JOptionPane.YES_OPTION || res ==0)//if res is 0, then the file does not exist yet
							{
							saving(outputDirectory, file.getName());
							done = true;
							}
						
						dialog.setVisible(false);
						
					}
					}
					});
				
			    dialog.addWindowListener(new WindowAdapter() {
			        public void windowClosing(WindowEvent e) {
			          dialog.setVisible(false);
			          done=true;
			        }
			      });
				
				while(!done)
				{
					dialog.setVisible(true);
				}
				
				this.savecount++;
				
			}

		}
		else if(event.getSource() == this.newButton || event.getSource() == this.newItem)
		{
			
			TextPad newTextPad = new TextPad();
			
		}
		else if(event.getSource() == this.exitItem)
		{
			//Custom button text
			Object[] options = {"Yes, please",
			                    "No, thanks",
			                    "Cancel"};
			int n = JOptionPane.showOptionDialog(null,
			    "Would you like like to save the file?",
			    "SAVE",
			    JOptionPane.YES_NO_CANCEL_OPTION,
			    JOptionPane.QUESTION_MESSAGE,
			    null,
			    options,
			    options[2]);
			//System.out.println(n);

			if(n == 0)
			{
				if(this.currentfile == null)
				{
					//custom title, warning icon
					JOptionPane.showMessageDialog(null,
					    "Please click on the save button on the top left corner or hit Ctrl-S!",
					    "warning",
					    JOptionPane.WARNING_MESSAGE);

				}
				else
				{
					saving(this.currentfile);
					this.dispose();
				}
			}
			else if(n ==1)
				this.dispose();
		}
	}//end of actionPerformed
	
	/**
	 * Check if a file exists in a directory.
	 * @param dir		The directory path which will be searched.
	 * @param filename	The file name which is being looked up.
	 * @return 	Return true if filenmae exists in dir, else false.
	 */
	public boolean isFileExists(String dir, String filename)
	{
	    File folder = new File(dir);
	    File[] listOfFiles = folder.listFiles();

	    for (int i = 0; i < listOfFiles.length; i++) {
	    	  if(listOfFiles[i].getName().equals(filename))
	    		  return true;
	    }
	    
		return false;
	}
	
	public boolean saving(String dir, String fn)
	{
		//File file = new File("C:/Users/yepc/Desktop/txtpad","txtpad.txt");
		File file = new File(dir,fn+".txt");
		
	    try {
	    	//creates BufferedWriter for writing
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			
			//write out column name to output file
		    out.write(this.logArea.getText());
		    
		    out.close();//close the file
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		this.currentfile = file;
		if(this.currentfile.exists())
		{
			this.saved=true;
			return true;
		}
		else
			return false;
		
	}
	
	public void saving(File f)
	{
	    try {
	    	//creates BufferedWriter for writing
			BufferedWriter out = new BufferedWriter(new FileWriter(f));
			
			//write out column name to output file
		    out.write(this.logArea.getText());
		    
		    out.close();//close the file
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

class MyFileChooser extends JFileChooser {
	  /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public JDialog createDialog(Component parent) throws HeadlessException {
	    return super.createDialog(parent);
	  }}
